#include "databoard.h"
#include "ui_databoard.h"
#include "binaryfile.h"
#include "textfile.h"
#include "unknownfile.h"
#include "auxclasses.h"
#include "dataformatwizard.h"
#include <QStandardItemModel>
#include <QModelIndex>
#include <QTreeView>
#include <QVBoxLayout>

DataBoard::DataBoard(QWidget *parent) :
        QWidget(parent),
        m_ui(new Ui::DataBoard)
{
    m_ui->setupUi(this);

    binaryDataFormatUI = new BinaryDataFormatUI;
    binaryDataFormatUI->setVisible(false);
    m_ui->layout_summary->insertWidget(0, binaryDataFormatUI);
    currentDataFormatUIIndex = -1;

    m_ui->button_modify->setVisible(false);
    m_ui->button_save->setVisible(false);

    // setup map between file suffix and file type
    fileSuffixTypeMap = new QMap<QString, EnumTypes::FileType>;
    fileSuffixTypeMap->insert(QString::fromAscii("nc"), EnumTypes::NetCDF);
    fileSuffixTypeMap->insert(QString::fromAscii("dat"), EnumTypes::Binary);
    fileSuffixTypeMap->insert(QString::fromAscii("txt"), EnumTypes::Text);
    
    // initialize data file information variables
    binaryFileList = new QList<BinaryFile *>;
    binaryFileGroupList = new QList<FileGroup *>;
    binaryFileGroupModel = new QStandardItemModel;
    treeView_binaryFileList = new TreeView;
    treeView_binaryFileList->setModel(binaryFileGroupModel);
    m_ui->layout_dataInfo->insertWidget(1, treeView_binaryFileList);

    textFileList = new QList<TextFile *>;
    textFileGroupList = new QList<FileGroup *>;
    textFileGroupModel = new QStandardItemModel;
    treeView_textFileList = new QTreeView;
    treeView_textFileList->setModel(textFileGroupModel);
    treeView_textFileList->setVisible(false);
    m_ui->layout_dataInfo->insertWidget(2, treeView_textFileList);


    unknownFileList = new QList<UnknownFile *>;
    unknownFileGroupList = new QList<FileGroup *>;
    unknownFileGroupModel = new QStandardItemModel;
    treeView_unknownFileList = new QTreeView;
    treeView_unknownFileList->setModel(unknownFileGroupModel);
    treeView_unknownFileList->setVisible(false);
    m_ui->layout_dataInfo->insertWidget(3, treeView_unknownFileList);


    connect(m_ui->comboBox_fileTypeChooser, SIGNAL(currentIndexChanged(QString)),
            this, SLOT(switchTreeViewFileType(QString)));
    connect(treeView_binaryFileList, SIGNAL(clicked(QModelIndex)),
            this, SLOT(switchGroupBoxSummary(QModelIndex)));
    connect(treeView_textFileList, SIGNAL(clicked(QModelIndex)),
            this, SLOT(switchGroupBoxSummary(QModelIndex)));
    connect(treeView_unknownFileList, SIGNAL(clicked(QModelIndex)),
            this, SLOT(switchGroupBoxSummary(QModelIndex)));

    connect(m_ui->button_modify, SIGNAL(clicked()), this, SLOT(modityDataFormat()));
    connect(m_ui->button_save, SIGNAL(clicked()), this, SLOT(saveDataFormat()));

    connect(treeView_binaryFileList, SIGNAL(showData(QModelIndex)),
            this, SLOT(showData(QModelIndex)));
    connect(treeView_binaryFileList, SIGNAL(deleteFile(QModelIndex)),
            this, SLOT(deleteFile(QModelIndex)));
}

DataBoard::~DataBoard()
{
    delete m_ui;
}

void DataBoard::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void DataBoard::switchTreeViewFileType(QString fileType)
{
    if (fileType == "binary file") {
        treeView_binaryFileList->setVisible(true);
        treeView_textFileList->setVisible(false);
        treeView_unknownFileList->setVisible(false);
        if (binaryDataFormatUI->isVisible() == false) {
            m_ui->button_modify->setVisible(false);
            m_ui->button_save->setVisible(false);
        }
    } else if (fileType == "text file") {
        treeView_binaryFileList->setVisible(false);
        binaryDataFormatUI->setVisible(false);
        treeView_textFileList->setVisible(true);
        treeView_unknownFileList->setVisible(false);
        if (true) {
            m_ui->button_modify->setVisible(false);
            m_ui->button_save->setVisible(false);
        }
    } else if (fileType == "unknown file") {
        treeView_binaryFileList->setVisible(false);
        binaryDataFormatUI->setVisible(false);
        treeView_textFileList->setVisible(false);
        treeView_unknownFileList->setVisible(true);
        if (true) {
            m_ui->button_modify->setVisible(false);
            m_ui->button_save->setVisible(false);
        }
    }
    currentDataFormatUIIndex = -1;
}

void DataBoard::switchGroupBoxSummary(const QModelIndex &index)
{
    if (treeView_binaryFileList->isVisible() == true) {
        int i = index.row();
        if (index.parent() == QModelIndex()) {
            if (currentDataFormatUIIndex == -1)
                binaryDataFormatUI->setVisible(true);
            BinaryFile *file = binaryFileList->at(binaryFileGroupList->at(i)->memberIndex->at(0));
            binaryDataFormatUI->setFrom(*file);
            binaryDataFormatUI->disable();
            currentDataFormatUIIndex = i;
            if (m_ui->button_modify->isVisible() == false)
                m_ui->button_modify->setVisible(true);
            if (m_ui->button_save->isVisible() == false)
                m_ui->button_save->setVisible(true);
        }
    } else if (treeView_textFileList->isVisible() == true) {
    } else if (treeView_unknownFileList->isVisible() == true) {
    }
}

void DataBoard::modityDataFormat()
{
    if (binaryDataFormatUI->isVisible() == true)
        binaryDataFormatUI->enable();
}

void DataBoard::saveDataFormat()
{
    if (binaryDataFormatUI->isVisible() == true) {
        binaryDataFormatUI->disable();
        int numFiles = binaryFileGroupList->at(currentDataFormatUIIndex)->memberIndex->size();
        for (int i = 0; i < numFiles; ++i) {
            int j = binaryFileGroupList->at(currentDataFormatUIIndex)->memberIndex->at(i);
            binaryDataFormatUI->setTo(binaryFileList->at(j));
        }
    }
}

void DataBoard::addNewFiles(const QStringList &filePathes)
{
    int i, j, k;
    bool isRepetitive;
    int numNewBinaryFiles = 0;
    int numNewTextFiles = 0;
    int numNewUnknownFiles = 0;
    for (i = 0; i < filePathes.size(); ++i) {
        QString fileName = filePathes.at(i).split('/').last();
        if (fileName.contains('.') == false) {
            isRepetitive = false;
            for (j = 0; j < unknownFileList->size(); ++j) {
                if (filePathes.at(i) == unknownFileList->at(j)->filePath) {
                    isRepetitive = true;
                    break;
                }
            }
            if (isRepetitive == false) {
                numNewUnknownFiles++;
                unknownFileList->append(new UnknownFile);
                k = unknownFileList->size()-1;
                unknownFileList->at(k)->filePath = filePathes.at(i);
                unknownFileList->at(k)->fileName = fileName;
            }
            continue;
        }
        QString fileSuffix = fileName.split(".", QString::SkipEmptyParts).last();
        switch (fileSuffixTypeMap->value(fileSuffix)) {
        case (EnumTypes::NetCDF) :
            break;
        case (EnumTypes::Binary) :
            isRepetitive = false;
            for (j = 0; j < binaryFileList->size(); ++j) {
                if (filePathes.at(i) == binaryFileList->at(j)->filePath) {
                    isRepetitive = true;
                    break;
                }
            }
            if (isRepetitive == false) {
                numNewBinaryFiles++;
                binaryFileList->append(new BinaryFile);
                k = binaryFileList->size()-1;
                binaryFileList->at(k)->filePath = filePathes.at(i);
                binaryFileList->at(k)->fileName = fileName;
            }
            break;
        case (EnumTypes::Text) :
            isRepetitive = false;
            for (j = 0; j < textFileList->size(); ++j) {
                if (filePathes.at(i) == textFileList->at(j)->filePath) {
                    isRepetitive = true;
                    break;
                }
            }
            if (isRepetitive == false) {
                numNewTextFiles++;
                textFileList->append(new TextFile);
                j = textFileList->size()-1;
                textFileList->at(k)->filePath = filePathes.at(i);
                textFileList->at(k)->fileName = fileName;
            }
            break;
        }
    }
    if (numNewBinaryFiles != 0 || numNewTextFiles != 0 || numNewUnknownFiles != 0) {
        DataFormatWizard *wizard = new DataFormatWizard(binaryFileList,
                                       binaryFileGroupList,
                                       binaryFileGroupModel,
                                       numNewBinaryFiles,
                                       textFileList,
                                       textFileGroupList,
                                       textFileGroupModel,
                                       numNewTextFiles,
                                       unknownFileList,
                                       unknownFileGroupList,
                                       unknownFileGroupModel,
                                       numNewUnknownFiles);
        wizard->show();
    }
}

void DataBoard::showData(const QModelIndex &index)
{
    QString dataType = m_ui->comboBox_fileTypeChooser->currentText();
    int groupIndex = index.parent().row();
    int fileIndexInGroupMember = index.row();
    int fileIndex;
    if (dataType == "binary file") {
        fileIndex = binaryFileGroupList->at(groupIndex)->memberIndex->at(fileIndexInGroupMember);
        binaryFileList->at(fileIndex)->readFile();
    } else if (dataType == "text file") {

    } else if (dataType == "unknown file") {

    }
}

void DataBoard::deleteFile(const QModelIndex &index)
{
    QString dataType = m_ui->comboBox_fileTypeChooser->currentText();
    QStandardItem *item;
    QString fileName;
    int groupIndex = index.parent().row();
    int fileIndexInGroupMember = index.row();
    if (dataType == "binary file") {
        item = this->binaryFileGroupModel->itemFromIndex(index);
        fileName = item->data(Qt::DisplayRole).toString();
        // remove from model
        binaryFileGroupModel->removeRow(item->row(), item->parent()->index());
        int fileIndex = binaryFileGroupList->at(groupIndex)->memberIndex->at(fileIndexInGroupMember);
        // remove from group member
        binaryFileGroupList->at(groupIndex)->memberIndex->removeAt(fileIndexInGroupMember);
        // remove from file list
        binaryFileList->removeAt(fileIndex);
        // adjust member indexes in group
        for (int i = 0; i < binaryFileGroupList->size(); ++i) {
            for (int j = 0; j < binaryFileGroupList->at(i)->memberIndex->size(); ++j) {
                int fileIndex1 = binaryFileGroupList->at(i)->memberIndex->at(j);
                if (fileIndex1 > fileIndex) {
                    this->binaryFileGroupList->at(i)->memberIndex->insert(j, fileIndex1-1);
                    this->binaryFileGroupList->at(i)->memberIndex->removeAt(j+1);
                }
            }
        }
        // check for empty group
        if (binaryFileGroupList->at(groupIndex)->memberIndex->size() == 0) {
            binaryFileGroupList->removeAt(groupIndex);
            binaryFileGroupModel->removeRow(groupIndex);
        }
        // check for no file and group left
        if (binaryFileGroupList->size() == 0 && binaryFileList->size() == 0) {
            binaryDataFormatUI->setVisible(false);
            m_ui->button_modify->setVisible(false);
            m_ui->button_save->setVisible(false);
            currentDataFormatUIIndex = -1;
        }
    } else if (dataType == "text file") {

    } else if (dataType == "unknown file") {

    }
}
